package com.scs.application.core.utils.excel;

import cn.afterturn.easypoi.excel.annotation.Excel;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity;
import com.scs.application.core.global.GlobalDictService;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.excel.annotation.ExcelAutoColumnSize;
import com.scs.application.core.utils.excel.annotation.ExcelComment;
import org.apache.poi.hssf.usermodel.HSSFClientAnchor;
import org.apache.poi.hssf.usermodel.HSSFRichTextString;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFClientAnchor;
import org.apache.poi.xssf.usermodel.XSSFRichTextString;

import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @description: excel导出增强，添加表头备注
 */
public class ExcelExportService extends cn.afterturn.easypoi.excel.export.ExcelExportService {

    private Class<?> pojoClass;

    @Override
    public void createSheet(Workbook workbook, ExportParams entity, Class<?> pojoClass, Collection<?> dataSet) {
        if (pojoClass == Map.class) {
            super.createSheet(workbook, entity, pojoClass, dataSet);
            return;
        }

        this.pojoClass = pojoClass;
        super.createSheet(workbook, entity, pojoClass, dataSet);

        ExcelAutoColumnSize autoColumnSize = pojoClass.getDeclaredAnnotation(ExcelAutoColumnSize.class);
        if (autoColumnSize == null || !autoColumnSize.enable()) {
            return;
        }

        Sheet sheet = workbook.getSheet(entity.getSheetName());
        Row row = sheet.getRow(0);
        for (int i = 0; i < row.getLastCellNum(); i++) {
            // 调整每一列宽度
            sheet.autoSizeColumn((short) i);
            // 解决自动设置列宽中文失效的问题
            sheet.setColumnWidth(i, sheet.getColumnWidth(i) * 17 / 10);
        }

    }

    @Override
    protected void insertDataToSheet(Workbook workbook, ExportParams entity, List<ExcelExportEntity> entityList, Collection<?> dataSet, Sheet sheet) {
        super.insertDataToSheet(workbook, entity, entityList, dataSet, sheet);

        if (pojoClass == null) {
            return;
        }

        int headerRowIndex = 0;
        if (entity.getTitle() != null) {
            headerRowIndex = 1;
        }

        Row headerRow = sheet.getRow(headerRowIndex);

        Field[] declaredFields = pojoClass.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            Excel excelField = declaredField.getAnnotation(Excel.class);
            if (excelField == null) {
                continue;
            }
            ExcelComment excelComment = declaredField.getAnnotation(ExcelComment.class);
            if (excelComment == null) {
                continue;
            }
            String commentValue = StringUtils.defaultString(excelComment.value());

            if (excelComment.notNull()) {
                commentValue += commentValue.endsWith("；") ? "必填" : "；必填";
            }

            if (StringUtils.isNotBlank(excelComment.dict())) {
                GlobalDictService dictService = GlobalDictService.getInstance();
                if (dictService != null) {
                    String dictLabels = dictService.getDictLabels(excelComment.dict(), "");
                    commentValue += commentValue.endsWith("；") ? "可选项：" + dictLabels : "；可选项：" + dictLabels;
                }
            }

            // 给表头添加备注
            Cell cell = findHeaderCell(headerRow, excelField.name());
            if (cell == null) {
                continue;
            }
            Drawing patr = sheet.createDrawingPatriarch();

            Comment comment = null;

            if (entity.getType() == ExcelType.HSSF) {
                comment = patr.createCellComment(
                        new HSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5)
                );
                comment.setString(new HSSFRichTextString(commentValue));
            } else {
                comment = patr.createCellComment(
                        new XSSFClientAnchor(0, 0, 0, 0, (short) 4, 2, (short) 6, 5)
                );
                comment.setString(new XSSFRichTextString(commentValue));
            }
            cell.setCellComment(comment);
        }
    }

    public Cell findHeaderCell(Row headerRow, String fieldName) {
        for (int i = 0; i < headerRow.getLastCellNum(); i++) {
            Cell cell = headerRow.getCell(i);
            if (fieldName.equalsIgnoreCase(cell.getStringCellValue())) {
                return cell;
            }
        }
        return null;
    }


}
